package com.example.aipdefficiency.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.aipdefficiency.dto.UserRegisterRequest;
import com.example.aipdefficiency.dto.UserRegisterResponse;
import com.example.aipdefficiency.entity.UserInfo;
import com.example.aipdefficiency.entity.UserRole;
import com.example.aipdefficiency.entity.WalletInfo;
import com.example.aipdefficiency.exception.BusinessException;
import com.example.aipdefficiency.mapper.UserInfoMapper;
import com.example.aipdefficiency.mapper.UserRoleMapper;
import com.example.aipdefficiency.mapper.WalletInfoMapper;
import com.example.aipdefficiency.util.JwtUtil;
import com.example.aipdefficiency.util.PasswordUtil;
import com.example.aipdefficiency.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class UserService {
    
    @Autowired
    private UserInfoMapper userInfoMapper;
    
    @Autowired
    private UserRoleMapper userRoleMapper;
    
    @Autowired
    private WalletInfoMapper walletInfoMapper;
    
    @Autowired
    private PasswordUtil passwordUtil;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private RedisUtil redisUtil;
    
    @Transactional
    public UserRegisterResponse register(UserRegisterRequest request) {
        // 1. 验证手机号格式 - 已通过@Pattern注解验证
        log.info("开始用户注册，手机号：{}", request.getMobile());
        
        // 2. 验证密码强度 - 已通过@Pattern注解验证
        
        // 3. 检查确认密码一致性
        if (!request.getPassword().equals(request.getConfirmPassword())) {
            throw new BusinessException("CONFIRM_PASSWORD_ERROR", "确认密码不一致");
        }
        
        // 4. 验证验证码有效性
        String verifyCodeKey = "verify_code:" + request.getMobile();
        Object storedCode = redisUtil.get(verifyCodeKey);
        if (storedCode == null || !storedCode.toString().equals(request.getVerifyCode())) {
            throw new BusinessException("VERIFY_CODE_ERROR", "验证码无效或已过期");
        }
        
        // 5. 检查手机号是否已注册
        QueryWrapper<UserInfo> mobileQuery = new QueryWrapper<>();
        mobileQuery.eq("mobile", request.getMobile());
        UserInfo existingUserByMobile = userInfoMapper.selectOne(mobileQuery);
        if (existingUserByMobile != null) {
            throw new BusinessException("MOBILE_ALREADY_EXISTS", "手机号已注册");
        }
        
        // 6. 检查用户名是否已存在
        QueryWrapper<UserInfo> usernameQuery = new QueryWrapper<>();
        usernameQuery.eq("username", request.getUsername());
        UserInfo existingUserByUsername = userInfoMapper.selectOne(usernameQuery);
        if (existingUserByUsername != null) {
            throw new BusinessException("USERNAME_ALREADY_EXISTS", "用户名已存在");
        }
        
        // 7. 创建用户账户
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername(request.getUsername());
        userInfo.setPassword(passwordUtil.encryptPassword(request.getPassword()));
        userInfo.setMobile(request.getMobile());
        userInfo.setUserType(request.getUserType());
        userInfo.setStatus(1); // 1-正常，0-禁用
        userInfo.setCreateAt(LocalDateTime.now());
        userInfo.setUpdateAt(LocalDateTime.now());
        
        int userResult = userInfoMapper.insert(userInfo);
        if (userResult <= 0) {
            throw new BusinessException("USER_CREATE_FAILED", "用户创建失败");
        }
        
        // 8. 初始化用户钱包
        WalletInfo walletInfo = new WalletInfo();
        walletInfo.setUserId(userInfo.getId());
        walletInfo.setBalance(BigDecimal.ZERO);
        walletInfo.setFrozenAmount(BigDecimal.ZERO);
        walletInfo.setTotalIncome(BigDecimal.ZERO);
        walletInfo.setTotalExpense(BigDecimal.ZERO);
        walletInfo.setCreateAt(LocalDateTime.now());
        walletInfo.setUpdateAt(LocalDateTime.now());
        
        int walletResult = walletInfoMapper.insert(walletInfo);
        if (walletResult <= 0) {
            throw new BusinessException("WALLET_CREATE_FAILED", "钱包创建失败");
        }
        
        // 9. 设置用户角色
        UserRole userRole = new UserRole();
        userRole.setUserId(userInfo.getId());
        userRole.setRoleCode(getRoleCode(request.getUserType()));
        userRole.setRoleName(getRoleName(request.getUserType()));
        userRole.setCreateAt(LocalDateTime.now());
        userRole.setUpdateAt(LocalDateTime.now());
        
        int roleResult = userRoleMapper.insert(userRole);
        if (roleResult <= 0) {
            throw new BusinessException("USER_ROLE_CREATE_FAILED", "用户角色创建失败");
        }
        
        // 10. 生成登录令牌
        String token = jwtUtil.generateToken(userInfo.getId(), userInfo.getUsername());
        
        // 删除验证码
        redisUtil.delete(verifyCodeKey);
        
        // 11. 返回注册结果
        UserRegisterResponse response = new UserRegisterResponse();
        response.setUserId(userInfo.getId());
        response.setUsername(userInfo.getUsername());
        response.setMobile(userInfo.getMobile());
        response.setUserType(userInfo.getUserType());
        response.setToken(token);
        
        log.info("用户注册成功，用户ID：{}", userInfo.getId());
        return response;
    }
    
    private String getRoleCode(Integer userType) {
        return switch (userType) {
            case 1 -> "PUBLISHER";
            case 2 -> "EXECUTOR";
            case 3 -> "DUAL_ROLE";
            default -> "NORMAL_USER";
        };
    }
    
    private String getRoleName(Integer userType) {
        return switch (userType) {
            case 1 -> "发布方";
            case 2 -> "执行方";
            case 3 -> "双重角色";
            default -> "普通用户";
        };
    }
} 